
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

using Swaf.BizObj;
using Swaf.Gui.AspNet2;
using Swaf.Security;

namespace Syrinx.Gui.AspNet
{
	public abstract class GridBizObjDisplay : Swaf.Gui.AspNet2.UserControl, IPostBackEventHandler
	{
		protected static string s_emptyRowText = "&nbsp;";
		protected int m_currentRowIndex = 0;
		protected int m_currentCellIndex = 0;
		protected string m_selectedRowId = null;
		protected IBizObjList m_bizobjs = null;
		protected Privileges m_editPrivilege = Privileges.Delete;

		protected int m_rowsPerBizObj = 1;
		protected int m_cellsPerBizObj = 4;
		protected string m_betweenBizObjRowStyle = "border-bottom: 2px solid black";
		protected string m_innerCellStyle = "border-bottom: 1px solid gray; border-right: 1px solid gray";
		protected string m_outerCellStyle = "border-bottom: 1px solid gray";
        protected string m_firstFieldName = "start", m_lastFieldName = "notes";

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
			registerClientScript();
		}

		public Privileges EditPrivilege
		{
			get	{return m_editPrivilege;}
			set {m_editPrivilege = value;}
		}

		protected class FieldInfo
		{
			public string BizObjFieldName;
			public MethodInfo SetupEditor;
			public MethodInfo SaveVal;
			public MethodInfo DisplayVal;

			public FieldInfo(string bizobjFieldName, MethodInfo setupEditor, MethodInfo saveVal, MethodInfo displayVal)
			{
				BizObjFieldName = bizobjFieldName;
				SetupEditor = setupEditor;
				SaveVal = saveVal;
				DisplayVal = displayVal;
			}
		}

		protected abstract FieldInfo[] Fields {get;}
		protected virtual void bizobjAdded(IBizObj newBizObj) { }
		protected virtual void bizobjUpdated(IBizObj updatedBizObj) { }
		protected virtual void bizobjSelected(IBizObj selBizObj) { }

		protected void updateBizObj(string id)
		{
			if (m_bizobjs == null)
				return;

			IBizObj bizobj = findInBizObjList(id);
			if (m_editPrivilege >= Privileges.Edit)
			{
				if (bizobj == null)
				{
					if (m_editPrivilege >= Privileges.Add)
					{
						bizobj = m_bizobjs.insertNew();
						bizobj.put("id", new Swaf.BGuid.Guid());
						bizobj.clearDirtyFlags();
					}
					else
					{
						Debug.Assert(true, "An id was selected that is not present in the given bizobjlist when the user doesn't have add privileges.");
						return;
					}
				}

				object[] callParams = new object[] { bizobj, null };
				foreach (FieldInfo field in Fields)
				{
					callParams[1] = findFormFor(field.BizObjFieldName);
					field.SaveVal.Invoke(this, callParams);
				}

				if (bizobj.isNew && bizobj.isDirty())
                {
                    bizobjAdded(bizobj);
                    bizobj.isNew = false;
                }
				else if (bizobj.isDirty())
					bizobjUpdated(bizobj);
			}
		}

		protected IBizObj findInBizObjList(string id)
		{
			IBizObj foundBizObj = null;
			if(m_bizobjs != null)
				foreach (IBizObj obj in m_bizobjs)
					if (obj.KeyValue.ToString().Replace("-", "") == id)
					{
						foundBizObj = obj;
						break;
					}
			return foundBizObj;
		}

		protected string findFormFor(string name)
		{
			foreach (string formItem in Page.Request.Form.AllKeys)
				if (formItem.StartsWith(UniqueID + "$" + name))
					return Page.Request.Form[formItem];
			return "";
		}

		protected void showBizObjs(Swaf.Gui.IBusinessProcess bizproc, IBizObjList bizobjs)
		{
			m_bizobjs = bizobjs;

			if (Page.Request.Form["__EVENTTARGET"] == this.ID)
			{
				string previousId = ViewState["CID"] as string;
				if (previousId != null && m_editPrivilege >= Privileges.Edit)
					updateBizObj(previousId);

				m_selectedRowId = Page.Request.Form["__EVENTARGUMENT"];
				ViewState["CID"] = m_selectedRowId;
			}
			else
				m_selectedRowId = ViewState["CID"] as string;

			if (m_selectedRowId != null)
			{
				IBizObj selectedBizObj = findInBizObjList(m_selectedRowId);
				if (selectedBizObj == null)
					m_selectedRowId = null;
				else
					bizobjSelected(selectedBizObj);
			}

			this.createControls();
		}

		public int NumRowsPerBizObj
		{
			get { return m_rowsPerBizObj; }
			set
			{
				if (value >= 2)
					m_rowsPerBizObj = 2;
				else
					m_rowsPerBizObj = 1;
			}
		}

		public void processNumRows(HtmlBlockInfo info)
		{
			info.Context["numRows"] = m_rowsPerBizObj;
			info.generateBlock(""); 
		}

		public void processBizObjs(HtmlBlockInfo info)
		{
			if (m_bizobjs != null)
			{
				if (m_editPrivilege >= Privileges.Add && (m_bizobjs.numElements == 0 || !m_bizobjs[m_bizobjs.Count - 1].isNew))
				{
					IBizObj newOne = m_bizobjs.insertNew();
					newOne.put("id", new Swaf.BGuid.Guid());
                    newOne.clearDirtyFlags();
				}

				bool readOnly = true;
				if (m_bizobjs != null)
				{
					foreach (IBizObj obj in m_bizobjs)
					{
						string id = obj.get("id").ToString().Replace("-", "");
						if (obj.isNew && m_selectedRowId == null)
						{
							ViewState["CID"] = id;
							readOnly = false;
						}
						else
							readOnly = !(m_editPrivilege >= Privileges.Edit && id == m_selectedRowId);
						info.Context["readOnly"] = readOnly;

						info.generateBlock(id);
						setupControlValues(obj, id, readOnly);
					}
				}
			}
		}

		public string getRowId()
		{
			int index = m_currentRowIndex++/m_rowsPerBizObj;
			if (index < m_bizobjs.Count)
				return m_bizobjs[index].get("id").ToString().Replace("-", "");
			else
				return "";
		}

		public string getRowStyle()
		{
			int curCellInRange = m_currentCellIndex++ % m_cellsPerBizObj;
			int index = (m_currentRowIndex-1);
			if (m_rowsPerBizObj == 2)
			{
				if (index % m_rowsPerBizObj != 0)
					return m_betweenBizObjRowStyle;
				else
					return (curCellInRange != 2) ? m_innerCellStyle : m_outerCellStyle;
			}
			else
			{
				return (curCellInRange != m_cellsPerBizObj-1) ? m_innerCellStyle : m_outerCellStyle;
			}
		}

		protected string getFieldValue(IBizObj obj, string name, string defaultVal)
		{
			object v = obj.get(name);
			if (v != null)
			{
				string v2 = v.ToString();
				return (v2 == "") ? defaultVal : v2;
			}
			return defaultVal;
		}

		protected void setupControlValues(IBizObj obj, string id, bool readOnly)
		{

			object[] callParams = new object[] {id, obj, readOnly};
			foreach (FieldInfo field in Fields)
				field.SetupEditor.Invoke(this, callParams);

		}

		protected virtual string setupTextForReadOnly(string txt, bool readOnly)
		{
			if (readOnly && (txt == null || txt == ""))
				txt = s_emptyRowText;
			return txt;
		}

		protected void registerClientScript()
		{
			if (!Page.ClientScript.IsClientScriptBlockRegistered(typeof(string), "GridTimeEntriesDisplay"))
			{
				string x = Page.GetPostBackEventReference(this, "");
				Page.ClientScript.RegisterClientScriptBlock(typeof(string), "GridTimeEntriesDisplay",
                @"
function rowSel(event)
{
  var currentTarget = event.currentTarget;
  if(currentTarget == null)
    currentTarget = event.srcElement;
//alert(event);
  __doPostBack('" + this.ID + @"', findTR(currentTarget).id);
}

function editSel(rowId)
{
}

function findTR(startEl)
{
  var parent = startEl;
  while(parent.tagName != 'TR' && parent != null)
{
    parent = parent.parentNode;
//    if(parent != null)
//alert(parent.tagName);
}
  if(parent != null && parent.tagName == 'TR')
	return parent;
  return null;
}

function findPrevTR(curTr)
{
    curTr = curTr.previousSibling;
    while(curTr != null)
        if(curTr.tagName == 'TR')
            return curTr;
        else
            curTr = curTr.previousSibling;
    return curTr;
}

function findNextTR(curTr)
{
    curTr = curTr.nextSibling;
    while(curTr != null)
        if(curTr.tagName == 'TR')
            return curTr;
        else
            curTr = curTr.nextSibling;
    return curTr;
}

function checkMoveRow(event)
{
  var currentTarget = event.currentTarget;
  if(currentTarget == null)
    currentTarget = event.srcElement;
  var srcId = currentTarget.name;//event.srcElement.name;
  var piece = srcId.substr(srcId.lastIndexOf('$')+1, 5);
  //alert(srcId + ' : ' + piece + ' : ' + event.keyCode + ' : ' + srcId.lastIndexOf('$'));
  if((piece == '" + m_lastFieldName + @"' && event.keyCode == 9) ||
     (piece == '" + m_firstFieldName + @"' && event.keyCode == 40))
  {
    var parent = findTR(currentTarget);
    //alert('a');
    if(parent != null)
    {
    //alert('b');
      //event.returnValue = false;
      var nEl = findNextTR(parent);
      if(nEl != null)
        __doPostBack('" + this.ID + @"', nEl.id);
      else
		__doPostBack('" + this.ID + @"', 'new');
    }
  }
  if(piece == 'start' && ((event.keyCode == 9 && event.shiftKey == true) || event.keyCode == 38))
  {
    //alert('c');
    var parent = findTR(currentTarget);
    if(parent != null)
    {
        var prEl = findPrevTR(parent);
       // alert(prEl);
      if(prEl != null)
      {
        //event.returnValue = false;
        //alert(prEl.id + ':' + prEl.tagName);
        __doPostBack('" + this.ID + @"', prEl.id);
      }
    }
  }
  
}
", true);
			}
		}

		public void RaisePostBackEvent(string eventArgument)
		{
			
		}
	}
}
